看雪论坛作者ID:镜中人24
居家隔离度日如年,为了打发时间我又重新将卸载数月之久的XX直播下载到手机上,从关注列表中找到一个之前挺喜欢的英雄联盟游戏主播,其主播风格基本没有改变还是之前喜欢的样子。与记忆中不同的一点,现在主播通过弹幕进行投票来决定当局游戏选择哪个英雄,但是由于在APP端限制一秒只能发送一条弹幕,外加本人手速着实的慢,十有八九都会错过自己想看的英雄。还有一周多的隔离时间,好不容易找到一个可以打发时间的事情,如果经常不能看到自己想看的内容,大概率用不了多久就会失去兴趣,万一再引发心理问题就严重咯!作为技术人员,何不搞它一波?
从主播口中了解到,现在的投票规则是主播提供几个英雄选项,粉丝弹幕输入对应的序号,且不会进行重复过滤。根据现在的规则,如果我们可以自动发送指定内容的弹幕,就可以实现我们想要的效果。
其一是APP端限制的一秒只可发送一条弹幕,如何突破这一限制?
其二是如何实现弹幕的自动发送?
1、首先,我们需要定位到当前Activity。手机启动APP并打开直播界面,命令行执行“adb shell dumpsys activity top”查看当前Activity,结果如下图所示:
2、然后,借助逆向工具jadx对XX的安装包进行反编译,并分析PlayerActivity的逻辑实现,虽然作了大量的混淆,还是可以找到如下图所示部分代码:
从图中所示的代码,我们可以看到XX是通过控制焦点来限制一秒钟只能发送一条弹幕,了解了限制的方式我们可以有多种手段突破该限制,例如直接调用setText来设置弹幕内容。
3、定位弹幕发送的位置,如果能够找到弹幕发送的函数实现,我们可以主动调用来实现弹幕的自动发送,但是事与愿违,受混淆的限制不能轻易的定位弹幕发送的位置,就我个人而言也不希望花费太多的时间。冷静思考一番,何不换一种思路,以开发的角度来定位弹幕发送的位置?
俗话说,细节决定成败。我们发送一条弹幕,并仔细观察这一个过程,其实不难发现在我们点击弹幕输入框的时候会蹦出软键盘,当我们输入弹幕内容后,需要点击“发送”按钮才会真正的发送弹幕。如果作为开发人员,我们该如何实现这一需求呢?其实实现该需求是比较简单的,无非就是软键盘的按键。在安卓开发的领域内提供了三种监听方法:
1、重写Activity的dispatchKeyEvent(KeyEvent event)方法;
2、使用OnKeyListener方法监听软键盘按键;
3、使用setOnEditorActionListener方法来监听。
上面三种方法,setOnEditorActionListener可以更精准的判断右下角按键情况,并且可对“Go”、“Done”、“search”键的情况做出更细分的操作。我们可以针对三种方法依次借助jadx的文本搜索功能进行搜索,最终基本确定采用了第三种方法。
如果只看文本搜索的结果,可以看到有多处都使用了这一方法,但是我们可以重点关注图中显示的最后一项,再回顾下第一步定位Activity输出的内容。
结合两张图片基本可以确定XX弹幕发送是如何监听软键盘的。
4、思考如何实现自动弹幕,我们可以跟踪一下setOnEditorActionListener的使用,如下图所示:
我们可以看到函数传递的参数是一个OnEditorActionListener对象,可以理解成一个回调,当用户点击软键盘的“发送”按钮后。最终会触发OnEditorActionListener对象所定义的onEditorAction函数,那么我们是否可以伪造参数来主动调用onEditorAction函数,实现弹幕的自动发送呢?
在前面的分析过程,我们提出一种方案,伪造参数主动调用onEditorAction函数,这种方案究竟是否可行,我们编写一个demo来做一下简单的验证。
1、界面布局的编写,布局中包括一个文本输入框EditText和一个用于主动发送弹幕的Button,图中红框属性即说明弹出带“发送”键的软键盘。
2、使用setOnEditorActionListener给EditText添加软键盘的监听事件,并如红框所示存储EditText对象和OnEditorActionListener对象。
根据代码内容,当用户点击发送后Logcat日志会输出EditText的输入内容及当前时间戳。
3、Button点击事件实现,每点击一次就相当于主动发送一次弹幕。
4、运行demo,我们先正常操作输入一个XX,之后点击三次按钮,日志输出内容如下所示:
从结果看,伪造参数主动调用onEditorAction函数来实现弹幕的自动发送是可行的,但是也出现了一个更为棘手的问题,如何注入到XX应用中?
基于AOSP,定制一个用于自动发送弹幕的系统,XX运行在该系统上。主要的修改涉及Launcher、Activity、TextViewsan个类,除此之外新增一个DanmuUtil类。
其中Launcher类即对Launcher程序源码进行修改,在其启动的过程中创建一个悬浮按钮,用户点击该按钮弹出一个输入框用于输入自动弹幕的文本,以及发送远程广播来控制自动弹幕的开关。
Activity类作为基类会在APP启动的过程中被加载,根据类名区分是否为分析过程第一步中的类,是的话则负责广播的注册、注销以及创建一个Handler来进行消息的分发,从而控制弹幕的自动发送。当接收到来自Launcher的广播,Activity会通知Handler分发消息或者清空消息。Handler每隔300毫秒分发一次自动弹幕的消息。
DanmuUtil对弹幕内容的写入、获取、以及发送等功能进行封装,当Activity中定义的Handler收到自动弹幕的消息后,会调用该类的sendDanmu方法进行自动发送弹幕。
TextView则是重写setOnEditorActionListener,判断当前TextView是否为用于发送弹幕的EditText,是的话则将当前对象和OnEditorActionListener对象传给DanmUtil,用于自动弹幕的实现。由于在写文章的时候,文中提及主播并没有进行投票,所以输入一个数字3,自动发送弹幕效果如下所示:
看雪ID:镜中人24
https://bbs.pediy.com/user-home-919715.htm
*本文由看雪论坛 镜中人24 原创,转载请注明来自看雪社区